{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DeriveGeneric #-}

module Game.Dusk.Tarot.Card where

import Control.Monad
import Data.Bifunctor (bimap, first)
import Data.Hashable
import Data.Text.Prettyprint.Doc
import GHC.Generics
import Generic.Data
import System.Random

import Game.Dusk.Tarot.Major (MajorArcanum(..))
import Game.Dusk.Tarot.Minor

import qualified Game.Dusk.Tarot.Major as Major

data Card
  = Major MajorArcanum
  | Minor Suit
          Value
  deriving (Eq, Generic)

instance Hashable Card

instance Enum Card where
  {-# INLINE toEnum #-}
  toEnum = gtoFiniteEnum
  {-# INLINE fromEnum #-}
  fromEnum = gfromFiniteEnum
  {-# INLINE enumFrom #-}
  enumFrom = gfiniteEnumFrom
  {-# INLINE enumFromThen #-}
  enumFromThen = gfiniteEnumFromThen
  {-# INLINE enumFromTo #-}
  enumFromTo = gfiniteEnumFromTo
  {-# INLINE enumFromThenTo #-}
  enumFromThenTo = gfiniteEnumFromThenTo

instance Bounded Card where
  {-# INLINE minBound #-}
  minBound = gminBound
  {-# INLINE maxBound #-}
  maxBound = gmaxBound

instance Pretty Card where
  pretty (Major arc) = pretty arc
  pretty (Minor s v) = pretty v <+> pretty "of" <+> pretty s

instance Random Card where
  {-# INLINE random #-}
  random = first toEnum . randomR bounds
    where
      bounds = join bimap fromEnum (minBound @Card, maxBound)
  {-# INLINE randomR #-}
  randomR (lo, hi) gen =
    first toEnum . flip randomR gen . join bimap fromEnum $ (lo, hi)

newtype GameEffect a = GameEffect
  { getGameEffect :: a
  }

instance Pretty (GameEffect Card) where
  {-# INLINE pretty #-}
  pretty x =
    case getGameEffect x of
      Major arc -> pretty . Major.GameEffect $ arc
      Minor suit val ->
        pretty $
        case (suit, val) of
          (_, Ace) -> "+1 to any Skill, or a new Skill at rating 1"
          (Wands, Page) -> "Positive Quality"
          (Wands, Knight) -> "Positive Quality"
          (Wands, Queen) -> "Language"
          (Wands, King) -> "Language"
          (_, Page) -> "Specialization in any Skill"
          (_, Knight) -> "New Skill at rating 1"
          (_, Queen) -> "+1 to any Skill"
          (_, King) -> "+1 to any Skill"
          (Swords, Two) -> "Specialization in a Physical Skill"
          (Swords, Three) -> "New Physical Skill at rating 1"
          (Swords, Four) -> "+1 Perception"
          (Swords, Five) -> "+1 Stealth"
          (Swords, Six) -> "+1 Athletics"
          (Swords, Seven) -> "+1 Drive"
          (Swords, Eight) -> "+1 to a Physical Skill used this session"
          (Swords, Nine) -> "+1 to any Physical Skill"
          (Swords, Ten) -> "+1 to any Physical Skill"
          (Pentacles, Two) -> "Specialization in a Technical Skill"
          (Pentacles, Three) -> "Technical Skill at rating 1"
          (Pentacles, Four) -> "+1 Electronics"
          (Pentacles, Five) -> "+1 Artisan"
          (Pentacles, Six) -> "+1 Rigging"
          (Pentacles, Seven) -> "+1 Research"
          (Pentacles, Eight) -> "+1 to a Technical Skill used this session"
          (Pentacles, Nine) -> "+1 to any Technical Skill"
          (Pentacles, Ten) -> "+1 to any Technical Skill"
          (Cups, Two) -> "Specialization in a Social Skill"
          (Cups, Three) -> "New Social Skill at rating 1"
          (Cups, Four) -> "+1 Bureaucracy"
          (Cups, Five) -> "+1 Empathy"
          (Cups, Six) -> "+1 Expression"
          (Cups, Seven) -> "+1 Persuasion"
          (Cups, Eight) -> "+1 to a Social Skill used this session"
          (Cups, Nine) -> "+1 to any Social Skill"
          (Cups, Ten) -> "+1 to any Social Skill"
          (Wands, Two) -> "Two new Backgrounds, each at rating 1"
          (Wands, Three) -> "One new Background at rating 2"
          (Wands, Four) -> "+2 to a Background used this session"
          (Wands, Five) -> "+2 to a Background used this session"
          (Wands, Six) ->
            "+1 to a Background used this session, and also any other Background"
          (Wands, Seven) -> "+1 to any two Backgrounds"
          (Wands, Eight) -> "+2 to any Background"
          (Wands, Nine) -> "+2 to any Background"
          (Wands, Ten) -> "Positive Quality"
